package com.superdaxue.rxsampledemo.utils;

import android.content.Context;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by ZX_CC on 2016/4/20.
 */

public abstract class BaseRecyclerAdapter <T> extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
    protected List <T> datas = new ArrayList<>();
    protected final int mLayoutItemId;
    protected boolean isScrolling;
    protected Context mContext;
    private OnRecyclerItemClickListener mListener;
    //填充布局类型
    private final int TYPE_NORMAL = 0 ;
    private final int TYPE_HEADER = 1;
    private final int TYPE_FOOTER = 2 ;

    //FooterView 和 HeaderView
    private View footerView;
    private View headerView;

    public BaseRecyclerAdapter(RecyclerView rv,int mLayoutItemId) {
        this. mContext =rv.getContext();
        this.mLayoutItemId = mLayoutItemId;
        rv.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                isScrolling = !(newState == RecyclerView.SCROLL_STATE_IDLE);
                if (!isScrolling) {
                    notifyDataSetChanged();
                }
            }
        });
    }

    public void setHeaderView(View headerView) {
        this.headerView = headerView;
        notifyItemInserted(0);
    }

    public void setFooterView(View footerView) {
        this.footerView = footerView;
        notifyItemInserted(getItemCount() - 1);
    }

    public void removedFooterView(){
        if (footerView != null){
            notifyItemRemoved(getItemCount()-1);
        }
    }

    @Override
    public int getItemViewType(int position) {
        if (headerView !=null && position ==0){
            return  TYPE_HEADER;
        }
        if (footerView != null && position + 1 == getItemCount()) {
            return TYPE_FOOTER ;
        }
        return TYPE_NORMAL ;
    }

    @Override
    public int getItemCount() {
        return datas.size() == 0? 0 :( footerView ==null ? 0:datas.size() + 1 );
    }


    public void setDataList(List <T> datas){
        if (datas != null){
           this.datas.clear();
           this.datas.addAll(datas);
           notifyDataSetChanged();
        }
    }

    public void setItemListener(OnRecyclerItemClickListener mListener){
        this.mListener = mListener;
    }
    private View.OnClickListener getOnClickListener(final int position){
         return new View.OnClickListener(){
             @Override
             public void onClick(View v) {
                 if (mListener != null & v != null){
                     mListener.onRecyclerItemClick(v,datas.get(position),position);
                 }
             }
         };
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(mContext);
        RecyclerView.ViewHolder holder = null;
        if (viewType == TYPE_FOOTER && footerView != null){
            holder = new FooterOrHeaderViewHolder(footerView);
        }else if(viewType == TYPE_HEADER && headerView != null){
            holder = new FooterOrHeaderViewHolder(headerView);
        }else{
            View view  = inflater.inflate(mLayoutItemId,parent,false);
            holder =new RecyclerHolder(view) ;
        }
        holder.setIsRecyclable(true);
        return holder;
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        if (getItemViewType(position) == TYPE_FOOTER || getItemViewType(position) == TYPE_HEADER){
            return;
        }
        position = getRealPosition(holder);
        bindViewData((RecyclerHolder) holder,datas.get(position),position,isScrolling);
        holder.itemView.setOnClickListener(getOnClickListener(position));
    }

    private int getRealPosition(RecyclerView.ViewHolder viewHolder){
        int position = viewHolder.getLayoutPosition();
        return headerView == null ? position : (position - 1);
    }

    public abstract void bindViewData(RecyclerHolder holder, T item, int position, boolean isScrolling);

    public interface OnRecyclerItemClickListener {
        void onRecyclerItemClick(View view, Object data, int position);
    }

    private class FooterOrHeaderViewHolder extends RecyclerView.ViewHolder {
        public FooterOrHeaderViewHolder(View view) {
            super(view);
        }
    }

    /**
     * 当使用GridLayoutManager时添加HeaderView和FooterView会调用这个方法
     */
    @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
        RecyclerView.LayoutManager manager = recyclerView.getLayoutManager();
        if(manager instanceof GridLayoutManager) {
            final GridLayoutManager gridManager = ((GridLayoutManager) manager);
            gridManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
                @Override
                public int getSpanSize(int position) {
                    if (getItemViewType(position) == TYPE_FOOTER || getItemViewType(position) == TYPE_HEADER){
                        return gridManager.getSpanCount();
                    }else{
                        return 1;
                    }
                }
            });
        }
    }
    /**
     * 当使用瀑布流添加HeaderView的时候会调用这个方法
     */
    @Override
    public void onViewAttachedToWindow(RecyclerView.ViewHolder holder) {
        super.onViewAttachedToWindow(holder);
        ViewGroup.LayoutParams lp = holder.itemView.getLayoutParams();
        if(lp != null&& lp instanceof StaggeredGridLayoutManager.LayoutParams
                && (holder.getLayoutPosition() == 0||holder.getLayoutPosition() == (getItemCount()-1))) {
            StaggeredGridLayoutManager.LayoutParams slp = (StaggeredGridLayoutManager.LayoutParams) lp;
            slp.setFullSpan(true);
        }
    }
}
